#pragma  once

#include <string>
using namespace std;

/*
 g0  [0, arrayLength)
 g1	[0, arrayLength)


 array	[XXXXXXXXXXXOOOOOOOXXXXXX]		X:Data, O:NO Data
 text	[0, g0) + [g1, arrayLength)			//
 gap		[g0, g1)

 */

class GapVector {
public:
	GapVector(int initLength = 10);
	virtual ~GapVector();
public:
	void Remove(size_t offset, size_t rmSize);
	void Insert(size_t offset, const char additems[], size_t addSize);
	void Insert(size_t offset, const string& s);
	inline void Append(const string& s) {
		Insert(Length(), s);
	}
	inline void Append(const char additems[], size_t addSize) {
		Insert(Length(), additems, addSize);
	}
	int Length() const;
	string GetString(size_t offset, size_t len) const;
	inline string GetString() const {
		return GetString(0, Length());
	}
protected:
	size_t Offset2Index(size_t offset) const;
	size_t Index2Offset(size_t index) const;
	//[from, to)范围内的索引发生了变化, 重载此函数以调整Position的index
	//from ==> from +delta
	//有可能gap是改变之前被调用, 也可能改变之后被调用
	virtual void OnIndexChange(size_t fromIndex, size_t toIndex, int delta);
	//[from, to)
	//有可能gap是改变之前被调用, 也可能改变之后被调用
	virtual void OnIndexRemove(size_t fromIndex, size_t toIndex);
private:
	void MoveData(size_t destIndex, size_t srcIndex, size_t length);
	size_t GetNewArraySize(size_t reqSize) const;
	bool InPart1(size_t index) const;
	bool InPart2(size_t index) const;
private:
	char* buffer;
	size_t arrayLength;
	size_t g0_;
	size_t g1_;
	static const size_t GROWTH_SIZE = 1024 * 512;
};
